package com.mycompany.managedbean;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import static com.mycompany.managedbean.Connector.client;
import static com.mycompany.managedbean.Connector.database;
import static com.mycompany.managedbean.TableBean.uniqueID;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

/**
 *
 * @author Trollgate
 */
public class LazyDataObjectModel extends LazyDataModel<DataObject> {

    private List<DataObject> datasource;
    private List<ColumnModel> columns;
    private Boolean isNew;
    private String selectedDatabase;
    private String selectedCollection;

    public LazyDataObjectModel(String selectedDatabase, String selectedCollection) {
        this.selectedCollection = selectedCollection;
        this.selectedDatabase = selectedDatabase;
        //this.isNew = true;
    }

    public LazyDataObjectModel(List<DataObject> datasource) {
        this.datasource = datasource;
    }
    
    @Override
    public List<DataObject> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
        System.out.println(first + "--"+ pageSize);
        return loadDatas(first, pageSize);
    }

    @Override
    public Object getRowKey(DataObject t) {
        return t.getUniqueID();
    }

    @Override
    public DataObject getRowData(String rowKey) {
        
         List<DataObject> datas = (List<DataObject>) getWrappedData();
        for (DataObject dataObject : datas) {
            if (dataObject.getUniqueID().equals(rowKey)) {
                return dataObject;
            }
        }
        return null;
    }

    public List<DataObject> loadDatas(int first, int pageSize) {
        System.out.println(selectedCollection + "--" + selectedDatabase);
        if (!selectedCollection.equals("") && !selectedDatabase.equals("")) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Collection Listed", selectedCollection);
            FacesContext.getCurrentInstance().addMessage(null, message);

            columns = new ArrayList<ColumnModel>();
            database = client.getDB(selectedDatabase);
            DBCollection collectionArray = database.getCollection(selectedCollection);
            List<DBObject> objList = collectionArray.find().skip(first).limit(pageSize).toArray();
            List<DataObject> values = new ArrayList<DataObject>();

            setRowCount(collectionArray.find().count());
            System.out.println("Row Count : " + collectionArray.find().count());
            int property = 0;
            for (DBObject dBObject : objList) {
                uniqueID++;
                HashMap<String, String> map = (HashMap<String, String>) dBObject.toMap();
                DataObject nodeObj = new DataObject();
                HashMap<String, String> newObj = new HashMap<String, String>();

                for (Map.Entry mapEntry : map.entrySet()) {

                    if (!isColumnExists(mapEntry.getKey().toString())) {
                        /*Create New Column*/
                        ColumnModel model = new ColumnModel(mapEntry.getKey().toString(), mapEntry.getKey().toString());
                        columns.add(model);
                        property++;
                    }

                    newObj.put(mapEntry.getKey().toString(), mapEntry.getValue().toString());
                    nodeObj.setMultimap(newObj);
                    nodeObj.setUniqueID(uniqueID);
                    nodeObj.setDbObject(dBObject);
                    //Set Pretty JSON Object
                    Gson gson = new GsonBuilder().setPrettyPrinting().create();
                    String json = gson.toJson(dBObject);
                    nodeObj.setOrjinalObject(json);
                }
                /*Added Column Map to DataObject*/
                values.add(nodeObj);
            }
            return values;
        }
        return null;
    }

    public boolean isColumnExists(Object compare) {
        for (ColumnModel columnModel : columns) {
            if (columnModel.getHeader().equals(compare)) {
                return true;
            }
        }
        return false;
    }

    public List<DataObject> getDatasource() {
        return datasource;
    }

    public void setDatasource(List<DataObject> datasource) {
        this.datasource = datasource;
    }

    public String getSelectedDatabase() {
        return selectedDatabase;
    }

    public void setSelectedDatabase(String selectedDatabase) {
        this.selectedDatabase = selectedDatabase;
    }

    public String getSelectedCollection() {
        return selectedCollection;
    }

    public void setSelectedCollection(String selectedCollection) {
        this.selectedCollection = selectedCollection;
    }

    public List<ColumnModel> getColumns() {
        return columns;
    }

    public void setColumns(List<ColumnModel> columns) {
        this.columns = columns;
    }

    public Boolean isIsNew() {
        return isNew;
    }

    public void setIsNew(Boolean isNew) {
        this.isNew = isNew;
    }

    /*Column Model*/
    static public class ColumnModel implements Serializable {

        private String header;
        private String property;

        public ColumnModel(String header, String property) {
            this.header = header;
            this.property = property;
        }

        public String getHeader() {
            return header;
        }

        public String getProperty() {
            return property;
        }
    }

}
